#ifndef __GLF_CONFIG_H_INCLUDED__
#define __GLF_CONFIG_H_INCLUDED__

// This system allow a project to use different glf_config for different solution.
//
// Under normal usage, it will include glf_config.h located in glf/include.
// This special glf_config #define GLF_USE_GLF_CONFIG_DEFAULT_LOCATION which
// then include the normal glf_config.h
//
// If a project include glf_config.vsprop and define a user macro in a local
// .vsprop named ConfigPath which point to the parent of glf_config (glf
// has such macro defined in common.vsprop); it can add 
// glf_config/{SolutionName}/glf_config.h to have custom glf_config.h
// per solution.
//
// This is useful for tool development.
#include <glf_config.h>


#include <glf/config/compiler.h>
#include <glf/config/platform.h>

namespace glf {
	void Breakpoint(); 

	enum Platform {
		//PLATFORM_WINDOWS,
		//PLATFORM_MACOSX,
		//PLATFORM_XBOX360,
		//PLATFORM_PS3,
		//PLATFORM_WII,
		//PLATFORM_IPHONE,
		//PLATFORM_NDS,
		//PLATFORM_PSP,
		//PLATFORM_BADA,
		//PLATFORM_JIL,
		//PLATFORM_SYMBIAN,
		//PLATFORM_MAEMO,
		//PLATFORM_LIMO,
		//PLATFORM_WINMO,
	};
} //namespace glf

#if !defined(GLF_RETAIL)
#   define GLF_RETAIL 0
#endif
#if !defined(GLF_RELEASE)
#   define GLF_RELEASE 0
#endif
#if !defined(GLF_DEBUG)
#   define GLF_DEBUG 0
#endif

#if !defined(GLF_USE_FILESTREAM_CALLBACK)
#   define GLF_USE_FILESTREAM_CALLBACK 0
#endif

#if !defined(GLF_USE_FILESTREAM_DBGSTATS)
#   define GLF_USE_FILESTREAM_DBGSTATS 0
#endif


#if GLF_RETAIL==0 && GLF_RELEASE==0 && GLF_DEBUG==0

	//GLF_RETAIL, GLF_RELEASE or GLF_DEBUG not defined

#if defined(_DEBUG) //default to debug

    #undef GLF_DEBUG
	#define GLF_DEBUG 1
	
#else //default to release

    #undef GLF_RELEASE
	#define GLF_RELEASE 1	

#endif

#endif

#if !defined(GLF_FORCE_DISABLE_DEBUGGER)
	#define GLF_FORCE_DISABLE_DEBUGGER 0
#endif

#if defined(GLF_RETAIL) && GLF_RETAIL

	#define GLF_USE_INLINE		1
	#define GLF_USE_ASSERT		0
	//#define GLF_USE_TRACE		0
	//#define GLF_USE_TRACK_LEAKS	0
	#define GLF_NDEBUG			1
	#define GLF_NRELEASE		1

	#if !defined(GLF_ENABLE_DEBUGGER)
		#define GLF_ENABLE_DEBUGGER 0
	#endif

#elif defined(GLF_RELEASE) && GLF_RELEASE

	#define GLF_USE_INLINE		1
#if _WIN32
	#define GLF_USE_ASSERT		1
#else
	#define GLF_USE_ASSERT		0
#endif
	//#define GLF_USE_TRACE		0
	//#define GLF_USE_TRACK_LEAKS	0
	#define GLF_NRETAIL			1
	#define GLF_NDEBUG			1

	#if (defined(WIN32) || defined(_WIN32)) && !GLF_FORCE_DISABLE_DEBUGGER
		#if defined(GLF_ENABLE_DEBUGGER)
			#undef GLF_ENABLE_DEBUGGER
		#endif
		#define GLF_ENABLE_DEBUGGER 1
	#elif !defined(GLF_ENABLE_DEBUGGER)
		#define GLF_ENABLE_DEBUGGER 0
	#endif

#elif defined(GLF_DEBUG) && GLF_DEBUG

	//#define GLF_USE_INLINE		0
	#define GLF_USE_ASSERT		1
	#define GLF_USE_TRACE		1
	#define GLF_USE_TRACK_LEAKS	1
	#define GLF_NRETAIL			1
	#define GLF_NRELEASE		1

	#if (defined(WIN32) || defined(_WIN32)) && !GLF_FORCE_DISABLE_DEBUGGER
		#if defined(GLF_ENABLE_DEBUGGER)
			#undef GLF_ENABLE_DEBUGGER
		#endif
		#define GLF_ENABLE_DEBUGGER 1
	#elif !defined(GLF_ENABLE_DEBUGGER)
		#define GLF_ENABLE_DEBUGGER 0
	#endif

#else

	#error "GLF_RETAIL, GLF_RELEASE or GLF_DEBUG not defined, defaulting to debug"
	
#endif

// Build the opposite flag (useful to avoid bad code coloring)
#if GLF_ENABLE_DEBUGGER
#	define GLF_DISABLE_DEBUGGER 0
#else
#	define GLF_DISABLE_DEBUGGER 1
#endif

//GLF_OVERRIDE_XXXX needs to be defined to 0 or 1

#ifdef GLF_OVERRIDE_INLINE
#undef GLF_USE_INLINE
#define GLF_USE_INLINE GLF_OVERRIDE_INLINE
#endif

#ifdef GLF_OVERRIDE_ASSERT
#undef GLF_USE_ASSERT
#define GLF_USE_ASSERT GLF_OVERRIDE_ASSERT
#endif

#ifdef GLF_OVERRIDE_TRACE
#undef GLF_USE_TRACE
#define GLF_USE_TRACE GLF_OVERRIDE_TRACE
#endif

#ifdef GLF_OVERRIDE_TRACK_LEAKS
#undef GLF_USE_TRACK_LEAKS
#define GLF_USE_TRACK_LEAKS GLF_OVERRIDE_TRACK_LEAKS
#endif

#undef GLF_INLINE

#if defined(GLF_USE_INLINE) && GLF_USE_INLINE
	#define GLF_INLINE inline
#else
	#define GLF_INLINE
#endif


#ifndef GLF_MAX_THREADS
#	define GLF_MAX_THREADS 16
#endif

/*
d -> debug info (can debug, step into, etc)
i -> inline function expanding
a -> assert
t -> trace
l -> ??
+---------+-------------------+
|         | d | i | a | t | l |
+---------+-------------------+
| debug   | x       x   x   x |
| release |     x   x   x     |
| retail  |     x             |
+---------+-------------------+
*/

//! Enable depth buffer usage
#if !defined(GLF_USE_DEPTH_BUFFER)
#   define GLF_USE_DEPTH_BUFFER        1
#endif

//! Enable stencil buffer usage
#if !defined(GLF_HAS_STENCIL_BUFFER)
#   define GLF_HAS_STENCIL_BUFFER      1
#endif

//! Enable virtual filestream
#if !defined(GLF_VIRTUAL_FILESTREAM)
#   define GLF_VIRTUAL_FILESTREAM        0
#endif

//! Force use of virtual filestream for win32 platform
#if (defined(WIN32) || defined(_WIN32)) && !GLF_VIRTUAL_FILESTREAM
#	undef GLF_VIRTUAL_FILESTREAM
#	define GLF_VIRTUAL_FILESTREAM 1
#endif

//! Maximum number of concurrent opened files
#if !defined(GLF_MAX_FILESTREAM)
#	define GLF_MAX_FILESTREAM 224 	// 255 is the maximum # of opened files on iOS, 
									// 31 files has been reserved in case some files are opened without glf.
#endif

//! Enable home data override.
//! Files in <home>/data (Documents/data in iphone) will have priority over <data> folder when opened with FileStream.
//! Useful to quickly modify data without sending whole application to device.
#if !defined(GLF_HOME_DATA_OVERRIDE)
#   define GLF_HOME_DATA_OVERRIDE        0
#endif

//! Define remote controller TCP port
#if !defined(GLF_REMOTE_CONTROLLER_PORT)
#	define GLF_REMOTE_CONTROLLER_PORT	7777
#endif
//! Backward compatibility
//! GLF_EMULATE_EXTERNAL_DISPLAYS is deprecated, use GLF_WINDOWS_EMULATE_EXTERNAL_DISPLAYS instead
#if defined(GLF_EMULATE_EXTERNAL_DISPLAYS) && !defined(GLF_WINDOWS_EMULATE_EXTERNAL_DISPLAYS)
#	define GLF_WINDOWS_EMULATE_EXTERNAL_DISPLAYS GLF_EMULATE_EXTERNAL_DISPLAYS
#endif

//! Disable external display emulation by default
#if !defined(GLF_WINDOWS_EMULATE_EXTERNAL_DISPLAYS) || !defined(GLF_GRAPHICAL_API_OPENGL)
#	undef GLF_WINDOWS_EMULATE_EXTERNAL_DISPLAYS
#	define GLF_WINDOWS_EMULATE_EXTERNAL_DISPLAYS 0
#endif

//! If platform is windows phone 8, force disable SDL.
#if GLF_PLATFORM_WP8
#	define GLF_WINDOWS_DISABLE_SDL
#endif


//! Enable svn infos
//#if !defined(GLF_USE_SVN_INFOS)
//#   define GLF_USE_SVN_INFOS 1
//#endif

#include <glf/core/macros.h>

namespace glf {

enum MemHint {
	MEMHINT_NONE		= 0x00000000,

	MEMHINT_ZERO		= 0x00000001,	//memset 0 after allocation
	MEMHINT_BACK		= 0x00000002,	//as opposed to front
	MEMHINT_BEST		= 0x00000004,	//best fit, as opposed to first fit
	MEMHINT_FAST		= 0x00000008,	//mem1 for wii
	MEMHINT_STATIC		= 0x00000010,	//for 'allocated once at the beginning and is never going to be released' allocation
	
	MEMHINT_ALIGN		= 0x0000f000,
	MEMHINT_ALIGN4		= 0x00001000,
	MEMHINT_ALIGN8		= 0x00002000,
	MEMHINT_ALIGN16		= 0x00003000,
	MEMHINT_ALIGN32		= 0x00004000,
	MEMHINT_ALIGN64		= 0x00005000,
	MEMHINT_ALIGN128	= 0x00006000,
	MEMHINT_ALIGN256	= 0x00007000,
	MEMHINT_ALIGN512	= 0x00008000,
	MEMHINT_ALIGN1024	= 0x00009000,

	//flags ends here
	MEMHINT_ALIGN_FLAG	= 0x0000f000,
	MEMHINT_POOL_FLAG	= 0x000f0000,
	
	MEMHINT_ALIGN_SHIFT	= 12,
	MEMHINT_POOL_SHIFT	= 16
};

}

GLF_ENUM_FLAG(glf::MemHint)

#include <glf/core/types.h>
#include <glf/core/assert.hpp>
#include <glf/core/macros.h>
#include <glf/core/inlines.h>
#include <glf/core/mem.h>
#include <glf/core/str.h>
#if GLF_AS_DLL
typedef void* (*T_FUNC_GLFALLOC)( size_t size );
typedef void (*T_FUNC_GLFFREE)( void* ptr );
typedef void* (*T_FUNC_GLFALLOC2)( size_t size, glf::MemHint hint );
#endif
#endif

